package cn.yr.common.manager;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TokenManager {

	/** TOKEN_VALID_INTERVAL token在多少时间内有效,默认30分钟 */
	private final static int TOKEN_VALID_INTERVAL = 30;
	private final static String SECRET_KEY_STRING = "4+fBAZMJ5ym79beaQpsBR4cQYa9TyI4n6dzY3iSxSJs=";
	private final static SecretKey key;
	static {
		key = Keys.hmacShaKeyFor(Base64.decode(SECRET_KEY_STRING));
	}

	/**
	 * Title:createJWT
	 * Description 创建jwt
	 * @return
	 * @throws Exception
	 */
	public static String createJWT() throws Exception {
		return createJWT(new HashMap());
	}

	public static String createJWT(String userId) {
		return createJWT("userId", userId);
	}

	public static String createJWT(String key, Object value) {
		HashMap<String, Object> map = new HashMap<>(1);
		map.put(key,value);
		return createJWT(map);
	}
	public static String createJWT(Map<String, Object> data) {
		return createJWT(data,TOKEN_VALID_INTERVAL);
	}

	public static String createJWT(Map<String, Object> data,int interval) {
		DateTime expireDate = DateUtil.offset(new Date(), DateField.MINUTE, interval);
		// 下面就是在为payload添加各种标准声明和私有声明了
		JwtBuilder builder = Jwts.builder()
				.setClaims(data)
				// 设置jti(JWT ID)：是JWT的唯一标识，根据业务需要，这个可以设置为一个不重复的值，主要用来作为一次性token,从而回避重放攻击。
				.setId(UUID.fastUUID().toString())
				// 设置过期信息
				.setExpiration(expireDate)
				// jwt的签发时间
				.setIssuedAt(new Date())
				// 设置签名使用的签名算法和签名使用的秘钥;
				.signWith(key);
		return builder.compact();
	}

	public static HashMap<String, Object> verifyToken(String token) {
		// 设置需要解析的jwt
		Claims body = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
		HashMap<String, Object> hashMap = new HashMap<>();
		hashMap.putAll(body);
		return hashMap;
	}


	/**
	 * <portal>Title: getUserIdByToken</portal>
	 * <portal>Description:解密jwt </portal>
	 * @date 2019年7月25日
	 * @param token
	 * @return
	 */
	public static String getUserIdByToken(String token) {
		HashMap kv = verifyToken(token);
		return kv.get("userId").toString();
	}

}